from __future__ import division

import os
import wx

import PIL.Image

from component import Formatter

class Image(wx.Window):
    """Image class
    
    Attributes:
        model: A Post model instance.
        image: A PIL image of model.file
    """
    
    def __init__(self, parent):
        wx.Window.__init__(self, parent, style=wx.BORDER_THEME)
        
        self._model = None
    
        self.bitmap = wx.StaticBitmap(self)
        self._blank = wx.EmptyBitmap(1 , 1)
        self.bind()
        
    def bind(self):
        self.Bind(wx.EVT_SIZE, self._onSize)
        self.Bind(wx.EVT_LEFT_DOWN, self._show)
        self.bitmap.Bind(wx.EVT_LEFT_DOWN, self._show)

    def _show(self, event):
        """Open image using default operating system image viewer"""
        
        if self.model and self.model.file.exists:
            os.startfile('"%s"' % self.model.file.path)
    
    @property
    def model(self):
        """A Post model associated with image"""
        
        return self._model
    
    @model.setter
    def model(self, model):
        self._model = model
        self._resized = True
        if self.draw(): self.setCursor()
        else: self.clear()
        
    def _onSize(self, event):
        self._resized = True
        self.draw()
        event.Skip()
    
    def setCursor(self):
        """Set tooltip information"""
        
        if not self.model: return
    
        self.SetCursor(wx.StockCursor(wx.CURSOR_HAND))
        self.bitmap.SetCursor(wx.StockCursor(wx.CURSOR_HAND))
    
    def clear(self):
        """Clear image"""
        
        self.Freeze()
        self.bitmap.Freeze()
        
        self._path = ''
        self._image = None
        self.bitmap.SetBitmap(self._blank)
        self.bitmap.ToolTip = None
        self.ToolTip = None
        self.SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
        self.bitmap.SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
        
        self.bitmap.Thaw()
        self.Thaw()
    
    _image = None
    
    @property
    def image(self):
        """A PIL image or None."""
        
        if not self.model or not self.model.file.image: return None
    
        if self._image is None or self._resized:
            image = self.model.file.image
            width, height = image.size
            if height > self.Size.height or width > self.Size.width:
                # Image needs resizing to fit the parent.
                # Use height as anchor.
                width, height = self.Size
                width = (height * image.size[0]) / image.size[1]
                if width > self.Size.width:
                    # Width is still wider than the container, switch to width
                    # as anchor.
                    width, height = self.Size
                    height = (width * image.size[1]) / image.size[0]
                size = (int(width), int(height))
                image = image.resize(size, PIL.Image.ANTIALIAS)
            self._image = image
            self._resized = False
            
        return self._image
        
    def draw(self):
        """Draw image.
        
        Returns:
            A boolean indicating whether drawing operation succeeds.
        """
        
        if not self.image: return False
        
        x = (self.Size.width - self.image.size[0]) / 2
        y = (self.Size.height - self.image.size[1]) / 2
        position = wx.Point(x, y)
        
        wxImage = wx.EmptyImage(*self.image.size)
        wxImage.SetData(self.image.convert('RGB').tostring())
        if self.image.mode[-1] == 'A':
            imageString = self.image.convert('RGBA').tostring()
            wxImage.SetAlphaData(imageString[3::4])
        
        self.Freeze()
        self.bitmap.Freeze()
        self.bitmap.SetPosition(position)
        self.bitmap.SetBitmap(wxImage.ConvertToBitmap())
        self.Refresh()
        self.bitmap.Thaw()
        self.Thaw()
        return True
